此會觀察模型做預測或決定時大致上運作過程,它會怎麼進行。
模型訓練好後,可以執行模型實體的 predict 函式來進行判斷訊號。
from tensorflow.keras.models import Sequential
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255
from tensorflow.keras import layers
from tensorflow.keras.models import Model
model = Sequential([
layers.Dense(512, activation="relu"),
layers.Dense(10, activation="softmax")
])
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.fit(train_images, train_labels, epochs=5, batch_size=128)
test_digits = test_images[0:10]
predictions = model.predict(test_digits)
print(predictions[0])
(1)
依此範例,首先會到 keras.engine.training.Model.predict 函式主體,會將傳遞的參數與訊號傳入keras.engine.data_adapter.DataHandler建構子中做設定,在做模型訓練時也是會將訓練函式的參數包成data_adapter.DataHandler 實體,這意味著模型執行預測也可以批次設定來執行(如fit時建立的data_adapter.DataHandler 實體可傳入epoch、batch_size)。
(2)
而參數也可以設定callback物件,如果傳入的 callbacks 參數list不是繼承 keras.callbacks.CallbackList 類別的實體 list,則會進行將callbacks 參數融入keras.callbacks.CallbackList 類別的動作,此類別也是 callback的Container。融入的過程中,也和訓練時一樣,最後keras.callbacks.CallbackList 實體一定會包含keras.callbacks.ProgbarLogger類別實體,與keras.callbacks.History類別實體。
(3)
接著叫用keras.engine.training.Model.make_predict_function函式,決定好每個predict step所要使用的predict_function。這邊利用類似closure的方式將函式預先保存至記憶體,在跑批次時將會使用到此塊記憶體。
(4)
執行的架構如下:
callbacks.on_predict_begin()
for _, iterator in data_handler.enumerate_epochs(): #epoch固定為1
for step in data_handler.steps():
callbacks.on_predict_batch_begin(step)
tmp_batch_outputs = self.predict_function(iterator)
callbacks.on_predict_batch_end(
end_step, {"outputs": batch_outputs}
)
callbacks.on_predict_end()
(5)
迴圈中主要執行的predict函式會找到 keras.engine.training.Model.predict_step:
會直接到keras.engine.data_adapter.unpack_x_y_sample_weight,將傳入的資料依照list或其它型別集合轉成tuple回傳。
隨後執行keras.engine.training.Model.call、keras.engine.base_layer.call,經過一些參數轉換與檢察、模型還沒build則補跑build的動作後,會再到keras.engine.sequential.call 執行模型call函式。
模型call函式一開始執行keras.engine.sequential._build_graph_network_for_inferred_shape,把input的張量維度設定好,接續至 keras.engine.functional._run_internal_graph 找出每個模型所建好的Layer node,依序執行 Layer.call。依本例為依序執行二層keras.layers.core.dense.call,主要做輸入input與本身Layer.kernel 的內積並回傳,供應用程式主體使用。(每層計算完會存到 keras.engine.sequential.outputs)
以上是模型做predict大致上的行為,紀錄於此。